home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Xconq 7.0d37 / source / mac / machelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  17.6 KB  |  613 lines  |  [TEXT/KAHL]

  1. /* Help for the Mac interface to Xconq.
  2.    Copyright (C) 1992, 1993, 1994, 1995 Stanley T. Shebs.
  3.  
  4. Xconq is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.  See the file COPYING.  */
  8.  
  9. #include "conq.h"
  10. #include "macconq.h"
  11.  
  12. /* Globals for the instructions window. */
  13.  
  14. WindowPtr instructionswin = nil;
  15.  
  16. TEHandle instructions_text = nil;
  17.  
  18. /* Globals for the help window. */
  19.  
  20. DialogPtr helpwin = nil;
  21.  
  22. TEHandle helptopic = nil;
  23.  
  24. TEHandle helptext = nil;
  25.  
  26. ControlHandle helpvscrollbar;
  27.  
  28. ControlHandle topicsbutton;
  29. ControlHandle helpbutton;
  30. ControlHandle prevbutton;
  31. ControlHandle nextbutton;
  32. ControlHandle backbutton;
  33.  
  34. static HelpNode *cur_help_node = NULL;
  35.  
  36. char *helpstring = NULL;
  37.  
  38. /* The help node that is the list of topics. */
  39.  
  40. static HelpNode *topics_help_node = NULL;
  41.  
  42. /* The help node that tells about how to use the help system. */
  43.  
  44. static HelpNode *help_help_node = NULL;
  45.  
  46. #define NODESTACKSIZE 50
  47.  
  48. HelpNode **nodestack;
  49.  
  50. int nodestackpos;
  51.  
  52. /* The instructions window. */
  53.  
  54. pascal void
  55. draw_instructions_text(WindowPtr win, short ditem)
  56. {
  57.     GrafPtr oldport;
  58.     short itemtype;  Handle itemhandle;  Rect itemrect;
  59.  
  60.     GetDItem(instructionswin, diInstructionsText, &itemtype, &itemhandle, &itemrect);
  61.     GetPort(&oldport);
  62.     SetPort(instructionswin);
  63.     TextSize(14);
  64.     TEUpdate(&itemrect, instructions_text);
  65.     /* This makes the title item draw big. */
  66.     TextSize(18);
  67.     SetPort(oldport);
  68. }
  69.  
  70. /* Bring up the dialog with instructions on how to play. */
  71.  
  72. void
  73. instructions_dialog()
  74. {
  75.     if (instructionswin == nil) {
  76.         create_instructions_dialog();
  77.     }
  78.     if (first_windows) {
  79.         GDHandle main_screen = GetMainDevice();
  80.         int main_screen_width, main_screen_height;
  81.         Rect tmprect = instructionswin->portRect;
  82.         Rect gdrect = (*main_screen)->gdRect;
  83.  
  84.         main_screen_width = gdrect.right - gdrect.left;
  85.         main_screen_height = gdrect.bottom - gdrect.top;
  86.         MoveWindow(instructionswin,
  87.                    main_screen_width - (tmprect.right - tmprect.left) - 3,
  88.                    main_screen_height - (tmprect.bottom - tmprect.top) - 3,
  89.                    FALSE);
  90.     }
  91.     ShowWindow(instructionswin);
  92.     SelectWindow(instructionswin);
  93. }
  94.  
  95. void
  96. create_instructions_dialog()
  97. {
  98.     Obj *instructions, *rest;
  99.     char *str;
  100.     Str255 tmpstr;
  101.     Rect destrect, viewrect;
  102.     short itemtype;  Handle itemhandle;  Rect itemrect;
  103.     Scorekeeper *sk;
  104.  
  105.     instructionswin = GetNewDialog(dInstructions, nil, (DialogPtr) -1L);
  106.     GetDItem(instructionswin, diInstructionsTitle, &itemtype, &itemhandle, &itemrect);
  107.     c2p(((mainmodule && mainmodule->title) ? mainmodule->title : ""), tmpstr);
  108.     SetIText(itemhandle, tmpstr);
  109.     GetDItem(instructionswin, diInstructionsText, &itemtype, &itemhandle, &itemrect);
  110.     SetDItem(instructionswin, diInstructionsText, itemtype, (Handle) draw_instructions_text, &itemrect);
  111.     destrect = itemrect;
  112.     viewrect = itemrect;
  113.     SetPort(instructionswin);
  114.     /* All text will be in Times. */
  115.     /* (should put sizes in a resource so can be edited) */
  116.     TextFont(times);
  117.     TextSize(14);
  118.     instructions_text = TENew(&destrect, &viewrect);
  119.     TESetSelect(0, 32767, instructions_text);
  120.     TEDelete(instructions_text);
  121.     if (mainmodule) {
  122.         instructions = mainmodule->instructions;
  123.         if (instructions != lispnil) {
  124.             if (stringp(instructions)) {
  125.                 str = c_string(instructions);
  126.                 TEInsert(str, strlen(str), instructions_text);
  127.             } else if (consp(instructions)) {
  128.                 for (rest = instructions; rest != lispnil; rest = cdr(rest)) {
  129.                     if (stringp(car(rest))) {
  130.                         str = c_string(car(rest));
  131.                         /* An empty line is a line break. */
  132.                         if (strlen(str) == 0) {
  133. #ifdef THINK_C
  134.                             str = "\r";
  135. #else
  136.                             str = "\n";
  137. #endif
  138.                         }
  139.                         TEInsert(str, strlen(str), instructions_text);
  140.                         TESetSelect(32767, 32767, instructions_text);
  141.                         /* Insert a blank between strings if none present, since they are
  142.                            usually word breaks. */
  143.                         if (str[strlen(str)-1] != ' ')
  144.                           TEInsert(" ", 1, instructions_text);
  145.                         TESetSelect(32767, 32767, instructions_text);
  146.                     }
  147.                 }
  148.             } else {
  149.                 /* error? */
  150.             }
  151.         } else {
  152.             if (mainmodule->blurb) {
  153.                 str = mainmodule->blurb;
  154.                 TEInsert(str, strlen(str), instructions_text);
  155. #ifdef THINK_C
  156.                 str = "\r\r";
  157. #else
  158.                 str = "\n\n";
  159. #endif
  160.                 TEInsert(str, strlen(str), instructions_text);
  161.             }
  162.             str = "(no instructions supplied)";
  163.             TEInsert(str, strlen(str), instructions_text);
  164.             for_all_scorekeepers(sk) {
  165.                 /* (should add better scorekeeper descriptions) */
  166. #ifdef THINK_C
  167.                 str = "\r";
  168. #else
  169.                 str = "\n";
  170. #endif
  171.                 TEInsert(str, strlen(str), instructions_text);
  172.                 str = "a scorekeeper";
  173.                 TEInsert(str, strlen(str), instructions_text);
  174.             }
  175.         }
  176.     } else {
  177.         /* this should be impossible? */
  178.     }
  179.     /* This makes the title item draw big. */
  180.     TextSize(18);
  181.     add_window_menu_item("Instructions", instructionswin);
  182. }
  183.  
  184. int
  185. hit_instructions_dialog(DialogPtr dialog, int itemhit, EventRecord *evt)
  186. {
  187.     switch (itemhit) {
  188.         case diInstructionsHelp:
  189.             /* Just jump to the help dialog. */
  190.             help_dialog();
  191.             break;
  192.     }
  193.     return TRUE;
  194. }
  195.  
  196. /* Help window. */
  197.  
  198. /* This is the top-level access to bring up the help window, can be called
  199.    anywhere, anytime. */
  200.  
  201. void
  202. help_dialog()
  203. {
  204.     if (helpwin == nil) {
  205.         create_help_window();
  206.     }
  207.     ShowWindow(helpwin);
  208.     SelectWindow(helpwin);
  209. }
  210.  
  211. void
  212. describe_menus(int arg, char *key, char *buf)
  213. {
  214.     strcat(buf, "File\n");
  215.     strcat(buf, "  The usual file operations.\n");
  216.     strcat(buf, "\n");
  217.     strcat(buf, "Edit\n");
  218.     strcat(buf, "  Select All selects all of your units at once.\n");
  219.     strcat(buf, "\n");
  220.     strcat(buf, "Find\n");
  221.     strcat(buf, "  Find Selected goes to the next map back and looks at the unit selected or viewed in the front window.\n");
  222.     strcat(buf, "\n");
  223.     strcat(buf, "Play\n");
  224.     strcat(buf, "  This is the main menu for unit actions.");
  225.     strcat(buf, "  Each item represents something that you can do to the currently selected units.\n");
  226.     strcat(buf, "  If an action is grayed out, then none of the selected units can do it.\n");
  227.     strcat(buf, "  Closeup shows details of the selected units.\n");
  228.     strcat(buf, "  Build brings up the construction dialog.\n");
  229.     strcat(buf, "Side\n");
  230.     strcat(buf, "  This menu is for things that affect your whole side.\n");
  231.     strcat(buf, "Windows\n");
  232.     strcat(buf, "  This menu does window control.\n");
  233.     strcat(buf, "View (when a map is front window)\n");
  234.     strcat(buf, "  Items toggle various display elements in the front map window.\n");
  235.     strcat(buf, "\n");
  236.     strcat(buf, "View (when a list is front window)\n");
  237.     strcat(buf, "  Items toggle various display elements in the front list window.\n");
  238.     strcat(buf, "\n");
  239. }
  240.  
  241. void
  242. describe_mouse(int arg, char *key, char *buf)
  243. {
  244.     strcat(buf, "In move-on-click mode:\n");
  245.     strcat(buf, "  The next unit that can do anything will be selected automatically.\n");
  246.     strcat(buf, "  Click once on a destination to move the selected unit there.\n");
  247.     strcat(buf, "\n");
  248.     strcat(buf, "In normal mode:\n");
  249.     strcat(buf, "  Click once on a unit to select it.\n");
  250.     strcat(buf, "  Drag to destination to move it.\n");
  251.     strcat(buf, "  Shift-click to select additional units.\n");
  252.     strcat(buf, "  Drag out rectangle to select all units inside.\n");
  253.     strcat(buf, "\n");
  254.     strcat(buf, "Command-click to moves all selected units to the clicked-on location.");
  255.     strcat(buf, "\n");
  256.     strcat(buf, "Combat is automatic if another side's unit is adjacent and clicked on.");
  257. }
  258.  
  259. void
  260. describe_keyboard(int arg, char *key, char *buf)
  261. {
  262.     describe_commands(arg, key, buf);
  263. }
  264.  
  265. void
  266. describe_help(int arg, char *key, char *buf)
  267. {
  268.     strcat(buf, "Xconq Help consists of a number of ``topics''.  ");
  269.     strcat(buf, "Topics include generic information about Xconq as ");
  270.     strcat(buf, "well as specific details of the game in progress.  ");
  271.     strcat(buf, "To navigate, click the buttons above.");
  272.     strcat(buf, "\n");
  273.     strcat(buf, "Topics: ");
  274.     strcat(buf, "Clicking this button shows you the list of topics.  ");
  275.     strcat(buf, "Clicking on a topic in the list takes you to it directly.");
  276.     strcat(buf, "\n");
  277.     strcat(buf, "Help:  ");
  278.     strcat(buf, "Clicking this button shows you the topic you're looking at right now.");
  279.     strcat(buf, "\n");
  280.     strcat(buf, "Next:  ");
  281.     strcat(buf, "Clicking this button goes to the next topic in order.");
  282.     strcat(buf, "\n");
  283.     strcat(buf, "Previous:  ");
  284.     strcat(buf, "Clicking this button goes to the previous topic in order.");
  285.     strcat(buf, "\n");
  286.     strcat(buf, "Back:  ");
  287.     strcat(buf, "Clicking this button goes to the last topic you were looking at.  ");
  288.     strcat(buf, "Multiple clicks take you farther and farther back.");
  289.     strcat(buf, "\n");
  290. }
  291.  
  292. void
  293. create_help_window()
  294. {
  295.     int h, v;
  296.     Rect helptopicrect, destrect, viewrect, vscrollrect;
  297.  
  298.     /* Create the window, color if possible, since images may be in color. */
  299.     if (hasColorQD) {    
  300.         helpwin = GetNewCWindow(wHelp, NULL, (WindowPtr) -1L);
  301.     } else {
  302.         helpwin = GetNewWindow(wHelp, NULL, (WindowPtr) -1L);
  303.     }
  304.     topicsbutton = GetNewControl(cTopicsButton, helpwin);
  305.     helpbutton = GetNewControl(cHelpButton, helpwin);
  306.     prevbutton = GetNewControl(cPrevButton, helpwin);
  307.     nextbutton = GetNewControl(cNextButton, helpwin);
  308.     backbutton = GetNewControl(cBackButton, helpwin);
  309.     SetPort(helpwin);
  310.     /* All text will be in Times. */
  311.     /* (should these be choosable?) */
  312.     TextFont(times);
  313.     /* Set up the topic title. */
  314.     TextSize(18);
  315.     SetRect(&helptopicrect, 45, 45, 305, 75); 
  316.     helptopic = TENew(&helptopicrect, &helptopicrect);
  317.     /* Set up the help text proper. */
  318.     TextSize(14);
  319.     h = window_width(helpwin);  v = window_height(helpwin);
  320.     SetRect(&viewrect, 5, 75, h - sbarwid, v - sbarwid); 
  321.     destrect = viewrect;
  322.     helptext = TENew(&destrect, &destrect);
  323.     /* Set up a vertical scrollbar. */
  324.     vscrollrect = helpwin->portRect;
  325.     vscrollrect.top = 75;
  326.     vscrollrect.bottom -= sbarwid - 1;
  327.     vscrollrect.left = vscrollrect.right - sbarwid;
  328.     vscrollrect.right += 1;
  329.     helpvscrollbar =
  330.         NewControl(helpwin, &vscrollrect, "\p", TRUE, 0, 0, 0, scrollBarProc, 0L);
  331.     HiliteControl(helpvscrollbar, 0);
  332.     /* Add the Mac-specific help nodes. */
  333.     /* (Note that these will appear in *reverse* order from here, because each
  334.        is being glued right after the first help node. */
  335.     add_help_node("menus", describe_menus, 0, firsthelpnode);
  336.     add_help_node("mouse", describe_mouse, 0, firsthelpnode);
  337.     add_help_node("keyboard", describe_keyboard, 0, firsthelpnode);
  338.     help_help_node = add_help_node("help", describe_help, 0, firsthelpnode);
  339.     topics_help_node = add_help_node("topics", describe_topics, 0, firsthelpnode);
  340.     cur_help_node = topics_help_node;
  341.     set_help_content(cur_help_node);
  342.     if (nodestack == NULL)
  343.       nodestack = (HelpNode **) xmalloc(NODESTACKSIZE * sizeof(HelpNode *));
  344.     nodestackpos = 0;
  345.     add_window_menu_item("Help", helpwin);
  346. }
  347.  
  348. void
  349. set_help_content(HelpNode *curnode)
  350. {
  351.     int i;
  352.     char *str;
  353.  
  354.     get_help_text(curnode);
  355.     /* Set the displayed topic title. */
  356.     TESetSelect(0, 32767, helptopic);
  357.     TECut(helptopic);
  358.     /* Copy in the new help topic text. */
  359.     TESetText(curnode->key, strlen(curnode->key), helptopic);
  360.     /* Set the displayed text. */
  361.     str = curnode->text;
  362. #ifdef THINK_C
  363.     /* Hack up newlines so that TextEdit recognizes them. */
  364.     for (i = 0; i < strlen(str); ++i) {
  365.         if (str[i] == '\n')
  366.           str[i] = '\r';
  367.     }
  368. #endif
  369.     helpstring = str;
  370.     /* Remove all the existing text. */
  371.     TESetSelect(0, 32767, helptext);
  372.     TECut(helptext);
  373.     /* Copy in the new help text. */
  374.     TESetText(helpstring, strlen(helpstring), helptext);
  375.     (*helptext)->destRect = (*helptext)->viewRect;
  376.     /* Update on the screen. */
  377.     draw_help();
  378.     adjust_help_scrollbar();
  379. }
  380.  
  381. void
  382. draw_help()
  383. {
  384.     Rect tmprect;
  385.     GrafPtr oldport;
  386.  
  387.     GetPort(&oldport);
  388.     SetPort(helpwin);
  389.     SetRect(&tmprect, 5, 40, 5 + 32, 40 + 32);
  390.     EraseRect(&tmprect);
  391.     if (cur_help_node->nclass == utypenode && is_unit_type(cur_help_node->arg)) {
  392.         draw_unit_image(helpwin, tmprect.left, tmprect.top, 32, 32,
  393.                         cur_help_node->arg, -1, 0);
  394.     } else if (cur_help_node->nclass == ttypenode && is_terrain_type(cur_help_node->arg)) {
  395.         draw_terrain_sample(tmprect, cur_help_node->arg); 
  396.     }
  397.     TextSize(18);
  398.     TEUpdate(&(helpwin->portRect), helptopic);
  399.     TextSize(14);
  400.     TEUpdate(&(helpwin->portRect), helptext);
  401.     SetPort(oldport);
  402.     adjust_help_scrollbar();
  403. }
  404.  
  405. void
  406. adjust_help_scrollbar()
  407. {
  408.     int lines, newmax, value;
  409.  
  410.     lines = (*helptext)->nLines;
  411.     newmax = lines - (((*helptext)->viewRect.bottom - (*helptext)->viewRect.top)
  412.                      / (*helptext)->lineHeight);
  413.     if (newmax < 0) newmax = 0;
  414.     SetCtlMax(helpvscrollbar, newmax);
  415.     value = ((*helptext)->viewRect.top - (*helptext)->destRect.top)
  416.             / (*helptext)->lineHeight;
  417.     SetCtlValue(helpvscrollbar, value);
  418. }
  419.  
  420. void
  421. activate_help(int activate)
  422. {
  423.     HiliteControl(helpvscrollbar, (activate ? 0 : 255));
  424. }
  425.  
  426. pascal void
  427. help_vscroll_proc(ControlHandle control, short code)
  428. {
  429.     int oldvalue, curvalue, minvalue, maxvalue, pagesize, jump;
  430.  
  431.     curvalue = GetCtlValue(control);
  432.     minvalue = GetCtlMin(control);
  433.     maxvalue = GetCtlMax(control);
  434.     pagesize = ((*helptext)->viewRect.bottom - (*helptext)->viewRect.top) /
  435.                 (*helptext)->lineHeight;
  436.     if (pagesize > 1) pagesize -= 1;
  437.     switch (code) {
  438.         case inPageDown:
  439.             jump = pagesize;
  440.             break;
  441.         case inDownButton:
  442.             jump = 1;
  443.             break;
  444.         case inPageUp:
  445.             jump = - pagesize;
  446.             break;
  447.         case inUpButton:
  448.             jump = -1;
  449.             break;
  450.         default:
  451.             jump = 0;
  452.             break;
  453.     }
  454.     oldvalue = curvalue;
  455.     curvalue = max(min(curvalue + jump, maxvalue), minvalue);
  456.     SetCtlValue(control, curvalue);
  457.     /* Calculate the actual jump and use it to adjust the text. */
  458.     jump = curvalue - oldvalue;
  459.     if (jump != 0)
  460.       TEScroll(0, - jump * (*helptext)->lineHeight, helptext);
  461. }
  462.  
  463. /* Respond to an event occurring in the help window. */
  464.  
  465. void
  466. do_mouse_down_help(Point mouse, int mods)
  467. {
  468.     ControlHandle control;
  469.     short part, value;
  470.     int i;
  471.     HelpNode *prevhelpnode = cur_help_node, *helpnode;
  472.  
  473.     part = FindControl(mouse, helpwin, &control);
  474.     if (control == topicsbutton) {
  475.         cur_help_node = topics_help_node;
  476.     } else if (control == helpbutton) {
  477.         cur_help_node = help_help_node;
  478.     } else if (control == prevbutton) {
  479.         cur_help_node = cur_help_node->prev;
  480.     } else if (control == nextbutton) {
  481.         cur_help_node = cur_help_node->next;
  482.     } else if (control == backbutton) {
  483.         if (nodestackpos > 0) {
  484.             cur_help_node = nodestack[--nodestackpos];
  485.         }
  486.     } else if (control == helpvscrollbar) {
  487.         if (part != 0) {
  488.             switch (part) {
  489.                 case inPageDown:
  490.                 case inDownButton:
  491.                 case inPageUp:
  492.                 case inUpButton:
  493.                     value = TrackControl(control, mouse, (ProcPtr) help_vscroll_proc);
  494.                     break;
  495.                 case inThumb:
  496.                     value = GetCtlValue(control);
  497.                     if ((part = TrackControl(control, mouse, nil)) != 0) {
  498.                         value -= GetCtlValue(control);
  499.                         if (value != 0) {
  500.                             TEScroll(0, value * (*helptext)->lineHeight, helptext);
  501.                         }
  502.                     }
  503.                     break;
  504.             }
  505.         }
  506.     } else if (PtInRect(mouse, &((*helptext)->viewRect))) {
  507.         TEClick(mouse, 0, helptext);
  508.         if (cur_help_node == topics_help_node) {
  509.             char strbuf[100], *cr1, *cr2;
  510.             int selstart = (*helptext)->selStart, selend = (*helptext)->selEnd;
  511.             CharsHandle chars = TEGetText(helptext);
  512.  
  513.             if (selstart == selend) {
  514.                 if (strchr("\r\n", *((*chars)+selstart)))
  515.                   --selstart;
  516.                 /* Manufacture a "selection" of the line clicked in. */
  517.                 for (cr1 = (*chars)+selstart; cr1 != (*chars); --cr1)
  518.                   if (strchr("\r\n", *cr1))
  519.                     break;
  520.                 cr2 = strchr((*chars)+selstart, '\r');
  521.                 if (cr2 == NULL)
  522.                   cr2 = strchr((*chars)+selstart, '\n');
  523.                 selstart = (cr1 != NULL ? cr1 - (*chars) + 1 : 0);
  524.                 selend = (cr2 != NULL ? cr2 - (*chars) : 0);
  525.                 if (selstart > selend)
  526.                   selstart = selend;
  527.             }
  528.             if (selstart != selend) {
  529.                 strncpy(strbuf, (*chars)+selstart, selend - selstart);
  530.                 strbuf[selend - selstart] = '\0';
  531.                 helpnode = find_help_node(cur_help_node, strbuf);
  532.                 if (helpnode != NULL) {
  533.                     cur_help_node = helpnode;
  534.                 } else {
  535.                     beep();
  536.                 }
  537.             } else {
  538.                 beep();
  539.             }
  540.         }
  541.     }
  542.     /* If we changed help nodes, get its contents and record on the node stack. */
  543.     if (prevhelpnode != cur_help_node) {
  544.         set_help_content(cur_help_node);
  545.         if (control != backbutton) {
  546.             if (nodestackpos >= NODESTACKSIZE) {
  547.                 for (i = 1; i < NODESTACKSIZE; ++i) nodestack[i - 1] = nodestack[i];
  548.                 nodestackpos = NODESTACKSIZE - 1;
  549.             }
  550.             nodestack[nodestackpos++] = prevhelpnode;
  551.         }
  552.     }
  553. }
  554.  
  555. void
  556. grow_help(int h, int v)
  557. {
  558.     EraseRect(&helpwin->portRect);
  559.     SizeWindow(helpwin, h, v, 1);
  560.     MoveControl(helpvscrollbar, h - sbarwid, 75);
  561.     SizeControl(helpvscrollbar, sbarwid + 1, v - 75 - sbarwid + 1);
  562.     (*helptext)->viewRect.right = h - sbarwid;
  563.     (*helptext)->viewRect.bottom = v - sbarwid;
  564.     (*helptext)->destRect.right = h - sbarwid;
  565.     TECalText(helptext);
  566.     InvalRect(&helpwin->portRect);
  567. }                    
  568.  
  569. void
  570. zoom_help(int part)
  571. {
  572.     int titleh, h, v;
  573.     Rect zoomrect;
  574.     GDHandle gd, zoomgd;
  575.  
  576.     EraseRect(&helpwin->portRect);
  577.     if (part == inZoomOut) {
  578.         if (!hasColorQD) {
  579.             /* If no Color QD, then there is only one screen. */
  580.             zoomrect = QD(screenBits).bounds;
  581.             InsetRect(&zoomrect, 4, 4);
  582.         } else {
  583.             for (gd = GetDeviceList(); gd != nil; gd = GetNextDevice(gd)) {
  584.                 if (TestDeviceAttribute(gd, screenDevice)) {
  585.                     if (TestDeviceAttribute(gd, screenActive)) {
  586.                         zoomgd = gd;
  587.                         break;
  588.                     }
  589.                 }
  590.             }
  591.             zoomrect = (*zoomgd)->gdRect;
  592.             if (zoomgd == GetMainDevice()) {
  593.                 zoomrect.top += GetMBarHeight();
  594.             }
  595.             titleh = 20; /* (should calc) */
  596.             zoomrect.top += titleh;
  597.             InsetRect(&zoomrect, 3, 3);
  598.         }
  599.         (*((WStateDataHandle) ((WindowPeek) helpwin)->dataHandle))->stdState = zoomrect;
  600.     }
  601.     ZoomWindow(helpwin, part, (helpwin == FrontWindow()));
  602.     h = window_width(helpwin);  v = window_height(helpwin);
  603.     MoveControl(helpvscrollbar, h - sbarwid, 0);
  604.     SizeControl(helpvscrollbar, sbarwid + 1, v - sbarwid + 1);
  605.     adjust_help_scrollbar();
  606.     (*helptext)->viewRect.right = h - sbarwid;
  607.     (*helptext)->viewRect.bottom = v - sbarwid;
  608.     (*helptext)->destRect.right = h - sbarwid;
  609.     TECalText(helptext);
  610.     /* This will force a full redraw at the next update. */
  611.     InvalRect(&helpwin->portRect);
  612. }
  613.